{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Backgrounds;

interface

uses Classes, Canvas, UIObjects, Fills, Plasma, Bitmaps, XMLHelper;

{$IFDEF DESIGNER}
const
  // Property categories and hints for designer
  CAT_BACKGROUND = 'Background';
  HINT_TYPE = 'defines the type of background (Bitmap, Fill or Plasma)';
  HINT_FILL = 'specifies the name of a fill item to use for the background';
  HINT_PLASMA = 'specifies the name of a plasma item to use for the background';
  HINT_BITMAP = 'specifies the name of a bitmap item to use for the background';
{$ENDIF}

type
  TAHMBackgroundType = (btNone, btBitmap, btFill, btPlasma);

  TAHMBackground = class(TAHMUIDisplayObject)
  private
    FType: TAHMBackgroundType;
    FFill: TAHMAbstractFill;
    FPlasma: TAHMPlasma;
    FBitmap: TAHMBitmap;
  protected
    procedure SetFill(Fill: TAHMAbstractFill);
    procedure SetPlasma(Plasma: TAHMPlasma);
    procedure SetBitmap(Bitmap: TAHMBitmap);
    procedure ClearProperties; override;
  public
    constructor Create(const Name: String); override;
    function RenderPreview: Boolean; override;
    procedure Render(Control: TObject; iX, iY, iWidth, iHeight: Single); override;
    procedure SeedObject; override;
    procedure Assign(Source: TPersistent); override;
    procedure SaveXMLBody(Lines: TStrings); override;
    procedure ParseFromXML(XML: TAHMXMLHelper); override;
    procedure BuildProperties(Properties: TAHMUIPropertyList); override;
  published
    property BackgroundType: TAHMBackgroundType read FType write FType;
    property Fill: TAHMAbstractFill read FFill write SetFill;
    property Plasma: TAHMPlasma read FPlasma write SetPlasma;
    property Bitmap: TAHMBitmap read FBitmap write SetBitmap;
  end;

  TAHMBackgroundList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddBackground(const InheritFrom, NewName: String): TAHMBackground;
    function GetBackground(const Name: String): TAHMBackground;
  end;


implementation

uses SysUtils, ApplicationManager, TagNames, XMLTags, Viewport, BaseControls,
     Logging, AHMTypes;

constructor TAHMBackgroundList.Create;
begin
  inherited Create;

  XMLTagName := TAG_BACKGROUNDS;
  ChildClass := TAHMBackground;
end;

function TAHMBackgroundList.AddBackground(const InheritFrom, NewName: String): TAHMBackground;
begin
  Result := TAHMBackground(Inherit(InheritFrom, NewName));
end;

function TAHMBackgroundList.GetBackground(const Name: String): TAHMBackground;
begin
  Result := TAHMBackground(GetObject(Name));
end;


//----------------------------------------------------------------------------//
constructor TAHMBackground.Create(const Name: String);
begin
  inherited Create(Name);

  XMLTagName := TAG_BACKGROUND;
  ObjectType := otBackgrounds;
  ImageIndex := Ord(otBackgrounds);
  PreviewEditable := False;
end;

procedure TAHMBackground.SetFill(Fill: TAHMAbstractFill);
begin
  FFill := Fill;
  if Assigned(Fill) then FType := btFill;
end;

procedure TAHMBackground.SetPlasma(Plasma: TAHMPlasma);
begin
  FPlasma := Plasma;
  if Assigned(Plasma) then FType := btPlasma;
end;

procedure TAHMBackground.SetBitmap(Bitmap: TAHMBitmap);
begin
  FBitmap := Bitmap;
  if Assigned(Bitmap) then FType := btBitmap;
end;

function TAHMBackground.RenderPreview: Boolean;
begin
  // Use fullscreen preview of plasma & fill backgrounds
  PreviewFullscreen := FType <> btBitmap;
  Result := inherited RenderPreview;
end;

procedure TAHMBackground.ClearProperties;
begin
  inherited;

  // Clear custom background properties
  FType := btNone;
  FFill := nil;
  FPlasma := nil;
  FBitmap := nil;
end;

procedure TAHMBackground.Render(Control: TObject; iX, iY, iWidth, iHeight: Single);
begin
  // Adjust background width & height to match container dimensions
  with Control as TAHMAbstractControl do
  begin
    Self.Width := Width;
    Self.Height := Height;
  end;

  // Pre-render our control if necessary
  inherited;

  // Render appropriate background content
  if (FType = btBitmap) and Assigned(FBitmap) then
    FBitmap.Render(Control)
  else if (FType = btFill) and Assigned(FFill) then
    FFill.Render(Control)
  else if (FType = btPlasma) and Assigned(FPlasma) then
    FPlasma.Render(Control);
end;

procedure TAHMBackground.SeedObject;
begin
{$IFDEF DESIGNER}
  if Ancestor = nil then
    with ApplicationManagerInstance.ThemeManager.VisualDescriptor do
      Fill := FillList.GetFill(DEFAULT_OBJECT_NAME);
{$ENDIF}
end;

procedure TAHMBackground.Assign(Source: TPersistent);
begin
  inherited Assign(Source);

  with Source as TAHMBackground do
  begin
    Self.BackgroundType := BackgroundType;
    Self.Fill := Fill;
    Self.Plasma := Plasma;
    Self.Bitmap := Bitmap;
  end;
end;

procedure TAHMBackground.SaveXMLBody(Lines: TStrings);
var
  oAncs: TAHMBackground;
begin
  // Determine which ancestor to compare against - real or empty
  oAncs := TAHMBackground(ObjectToCompare);

  // Only populate attributes that differ from our ancestor
  if (FType <> btNone) and (FType <> oAncs.BackgroundType) then
  begin
    if (FType = btBitmap) and (FBitmap <> nil) and (FBitmap <> oAncs.Bitmap) then
      Lines.Add(TABS[3] + FBitmap.XMLReference)
    else if (FType = btFill) and (FFill <> nil) and (FFill <> oAncs.Fill) then
      Lines.Add(TABS[3] + FFill.XMLReference)
    else if (FType = btPlasma) and (FPlasma <> nil) and (FPlasma <> oAncs.Plasma) then
      Lines.Add(TABS[3] + FPlasma.XMLReference);
  end;
end;

procedure TAHMBackground.ParseFromXML(XML: TAHMXMLHelper);
var
  sName: String;
  BackNode, PropsNode: TAHMXMLNode;
begin
  // Initialise parsing nodes
  BackNode := XML.CurrentNode;
  PropsNode := nil;

  // We support a number of background types - only expect one element here
  while XML.NextElement(BackNode, PropsNode) do
    with ApplicationManagerInstance.ThemeManager.VisualDescriptor do
    begin
      // All background types have a name attribute
      sName := XML.GetAttribute(ATTR_NAME);

      if (XML.CurrentElement = TAG_FILL) or
         (XML.CurrentElement = TAG_GRADEDFILL) or
         (XML.CurrentElement = TAG_LINEARFILL) then
        Fill := FillList.GetFill(sName)
      else if XML.CurrentElement = TAG_PLASMA then
        Plasma := PlasmaList.GetPlasma(sName)
      else if XML.CurrentElement = TAG_BITMAP then
        Bitmap := BitmapList.GetBitmap(sName);
    end;
end;

procedure TAHMBackground.BuildProperties(Properties: TAHMUIPropertyList);
begin
{$IFDEF DESIGNER}
  inherited;

  // Build custom background properties
  Properties.Add('Type', 'BackgroundType', CAT_BACKGROUND, HINT_TYPE);
  Properties.Add('Fill', 'Fill', CAT_BACKGROUND, HINT_FILL);
  Properties.Add('Plasma', 'Plasma', CAT_BACKGROUND, HINT_PLASMA);
  Properties.Add('Bitmap', 'Bitmap', CAT_BACKGROUND, HINT_BITMAP);
{$ENDIF}
end;

end.
